package io.renren.modules.wcs.taskPool;

import com.ioserver.bean.Union_DataType;
import io.renren.modules.ioserver.IOServerService;
import io.renren.modules.wcs.entity.DDJJobEntity;
import io.renren.modules.wcs.enums.DDJStatusEnum;
import io.renren.modules.wcs.enums.IOServerEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Callable;

/**
 * @Author: 蔡翔
 * @Date: 2019/10/28 15:01
 * @Version 1.0
 *
 * 返回值：
 * -1 代表 IOServer 写入异常
 * -2 代表 堆垛机在执行任务途中 出现故障。
 * -3 代表 重置称重plc 失败。  (这种报错，只要记录日志，然后相同的任务重新发起就行了)
 * -4 代表 在出库的时候，称重平台上已经有货了。 （这个时候就要把 l_start 给置为false  和 end 置为true）
 * 1 代表 堆垛机执行成功
 * 2 代表 重置任务失败。
 * 3 代表 分发任务失败
 * 4 代表 软启动成功
 *
 * status : work
 */

//如果实现 Runnable 返回值是 void ，，如果是Callable<T> 返回的是T
public class DDJCreateTaskRunnable<T> implements Callable<T> {


    private final static Logger logger = LoggerFactory.getLogger(DDJCreateTaskRunnable.class);
    private IOServerService ioServerService;
    //状态量 常量
    private static final Integer IOServerWriteExcep = -1;
    private static final Integer DDJRunningFault = -2;
    private static final Integer DDJFinishedSuccess = 1;
    private static final Integer ResetTaskFail = 2;
    private static final Integer SendTaskFail = 3;
    private static final Integer GracefulShutdownSuccess = 4;


    /**
     * 终点
     **/
    private String targetPosition = null;
    /**
     * 起点
     **/
    private String takePosition = null;
    /**
     * 称重plc位置、入库或者出库
     **/
    private Integer position = null;
    private Integer weightPLCType = null;



    /**
     * 优雅关闭
     **/
    private boolean switchs = true;

    private Integer deviceStatus;
    private Integer remoteMode;

    public DDJCreateTaskRunnable(){

    }
    public synchronized void initialDDJCreateTaskRunnable(IOServerService ioServerService,DDJJobEntity ddjJobEntity){
        this.takePosition = ddjJobEntity.getTakePosition();
        this.targetPosition = ddjJobEntity.getTargetPosition();
        this.ioServerService = ioServerService;
        this.position = ddjJobEntity.getPosition();
        this.weightPLCType = ddjJobEntity.getType();
        this.switchs = true;
    }

    @Override
    public synchronized T call() throws Exception {
        String PrefixLog = "在执行取货位:"+takePosition+",目标位："+targetPosition+"的时候出现：";
        if(this.weightPLCType == 1){
            logger.info("==============(入库开始)现在正在执行取货位:"+takePosition+",目标位："+targetPosition+"(入库开始)====================");
        }else {
            logger.info("==============(出库开始)现在正在执行取货位:"+takePosition+",目标位："+targetPosition+"(出库开始)====================");
        }

        Integer i = -1;
        Integer j = -1;
        Integer z = -1;
        Integer listenDeviceStatus = -1;

        //todo 注意ioserver 和 java 变量类型对应，否则取得值不一样，对代码逻辑有影响。
        while (true){

            Integer is= 1;

            deviceStatus = ioServerService.getValueByName(IOServerEnum.Device_Status.getCollectionPointName()).i2Val.intValue();

            remoteMode = ioServerService.getValueByName(IOServerEnum.Control_Mode.getCollectionPointName()).i2Val.intValue();

            if(deviceStatus.equals(DDJStatusEnum.Device_Status_FREE.getDeviceStatus()) && remoteMode.equals(5)){
                /**
                 * 重置  称重plc  的L_Start
                 **/
                //入库
                //叫堆垛机之前 把之前称重的plc 的lstart 置为false
                /*if(this.weightPLCType == 1){
                    if(!resetWeightPLC(this.weightPLCType, this.position)){
                        logger.info(PrefixLog+",入库的时候 给堆垛机下发任务之前，重置称重plc LStart 失败。");
                        return (T)new Integer(-3);
                    }
                }*/

                //出库
                if(this.weightPLCType == 2){
                    //每次出库的时候都要  把 end 置为false，，， OUT_START 置为 true
                    if(!endWeightPLCEnd(this.position)){
                        logger.info(PrefixLog+",出库的时候 给堆垛机下发任务之前，重置称重plc First_End 失败。(End都要重置一下)");
                        return (T)new Integer(IOServerWriteExcep);
                    }
                    if(!openWeightPLCStart(2,this.position)){
                        //这里LStart 要开启一下为了下面的detectOutFault(this.position)做准备，，为了检测称重平台上是否有障碍物
                        logger.info(PrefixLog+",出库的时候 给堆垛机下发任务之前，重置称重plc LStart 失败。");
                        return (T)new Integer(IOServerWriteExcep);
                    }
                    Thread.sleep(2000);
                    //返回false 就是 异常
                    if(!detectOutFault(this.position)){
                        logger.info(PrefixLog+",出库的时候 给堆垛机下发任务之前，发现平台上有障碍物，自动取消本次回库任务，给出提示等把这个障碍物移除再出库。");
                        return (T)new Integer(-4);
                    }
                }

                //任务开始之前先把PC_Status 置为 0  (重置)
                Integer integerPCStatus = ioServerService.setTagValue(IOServerEnum.PC_Status.getCollectionPointName(), "0", 1);
                if(integerPCStatus!=0){
                    logger.info(PrefixLog+",调用堆垛机开始之前，重置PCStatus 异常。");
                    return (T)new Integer(IOServerWriteExcep);
                }
                //设备空闲，才可以发起任务
                try {
                    i = ioServerService.setTagValue(IOServerEnum.Take_Position.getCollectionPointName(), takePosition, 2);
                    j = ioServerService.setTagValue(IOServerEnum.Target_Position.getCollectionPointName(), targetPosition, 2);
                }catch (Exception e){
                    logger.info(PrefixLog+"ioserver写入 起点终点 的时候异常,异常是："+e);
                    if(!resetTask()){
                        logger.info(PrefixLog+"，发起堆垛机任务，起点终点 IOServer 写入异常，并且重置任务的时候也异常");
                        return (T)new Integer(ResetTaskFail);
                    }
                    return (T)new Integer(IOServerWriteExcep);
                }
                if(i == 0 && j == 0){
                    //ioserver写入成功
                    Thread.sleep(500);
                    try {
                        z = ioServerService.setTagValue(IOServerEnum.L_Start.getCollectionPointName(),DDJStatusEnum.TRUE.getDeviceStatus().toString(), 4);
                    }catch (Exception e){
                        logger.info(PrefixLog+"ioserver写入 L_start的时候 异常,异常是："+e);
                        if(!resetTask()){
                            logger.info(PrefixLog+"ioserver写入 L_start的时候 异常,异常是："+e+"并且 重置 堆垛机也是失败");
                            return (T)new Integer(ResetTaskFail);
                        }
                        return (T)new Integer(IOServerWriteExcep);
                    }

                    if(z == 0){
                        logger.info("把 l_start 置为true，未发生异常的情况下， l_start的结果是："+ioServerService.getValueByName(IOServerEnum.L_Start.getCollectionPointName()).bitVal+";;z:"+z);
                        while (true){
                            Thread.sleep(500);
                            Boolean lstart = ioServerService.getValueByName(IOServerEnum.L_Start.getCollectionPointName()).bitVal;

                            if(lstart){
                                break;
                            }
                            else if(!lstart){
                                z = ioServerService.setTagValue(IOServerEnum.L_Start.getCollectionPointName(),DDJStatusEnum.TRUE.getDeviceStatus().toString(), 4);
                            }
                        }
                        //堆垛机 启动成功
                        logger.info(PrefixLog+"发起任务成功");
                        //开始监听 堆垛机是否完成
                        Integer reback = -1;
                        Integer flatOfOutStart = -1;
                        while (true && switchs){
                            listenDeviceStatus = ioServerService.getValueByName(IOServerEnum.Device_Status.getCollectionPointName()).i2Val.intValue();
                            if(listenDeviceStatus.equals(Integer.valueOf(DDJStatusEnum.Device_Status_FINISHED.getDeviceStatus().toString()))){
                                // 往ioserver写入 16进制88. 引入PC_Status目的是为了 告诉电控 Device_Status 状态我们收到了 ，你们可以重置了。。其实就相当于一次握手，避免数据我们还没有读到 它们就重置了
                                //执行成功后 把PC_STATUS 置为88 转成88后电控就知道 这时候它们可以重置变量了，，如果出现故障 那么是电容屏解决故障然后重置的。
                                String feedback = "88";
                                try {
                                    // 反馈信息，后面要修改到 其他plc变量。
                                    reback = ioServerService.setTagValue(IOServerEnum.PC_Status.getCollectionPointName(), feedback, 1);
                                }catch (Exception e){
                                    logger.info(PrefixLog+"，任务是执行成功了，但是给PCStatus写入88的时候 ioserver写入异常,异常是："+e);
                                    if(!resetTask()){
                                        logger.info(PrefixLog+"，任务是执行成功了，但是给PCStatus写入88的时候 ioserver写入异常,异常是："+e+"并且重置堆垛机也发生异常");
                                        return (T)new Integer(ResetTaskFail);
                                    }
                                    return (T)new Integer(IOServerWriteExcep);
                                }
                                if(reback == 0){
                                    //todo 给完88 他那边会重置，然后得到Device_Status ，我们监听到Device_Status==1 的时候把88置为0
                                    while (true){
                                        Thread.sleep(100);
                                        Integer deviceStatusTemp = ioServerService.getValueByName(IOServerEnum.Device_Status.getCollectionPointName()).i2Val.intValue();
                                        if(deviceStatusTemp==1){
                                            ioServerService.setTagValue(IOServerEnum.PC_Status.getCollectionPointName(), "0", 1);
                                            break;
                                        }else {
                                            continue;
                                        }
                                    }

                                    //执行完毕 ，并且给plc 反馈信息写入成功。
                                    logger.info(PrefixLog+"任务结束，执行任务完成。");
                                    //成功以后 是否要重置任务
                                    if(!resetTask()){
                                        logger.info(PrefixLog+"任务结束，执行任务完成。但是重置的时候失败了");
                                        return (T)new Integer(ResetTaskFail);
                                    }
                                    return (T)new Integer(DDJFinishedSuccess);
                                }
                            }else if(listenDeviceStatus.equals(Integer.valueOf(DDJStatusEnum.Device_Status_FAULT.getDeviceStatus()))){
                                //todo 故障1 发生故障后执行的后序操作，，因为不涉及业务，可以返回一个异常给上层系统，让他们自己去提取所需要的错误
                                logger.info(PrefixLog+",堆垛机执行任务的过程中出现Fault");

                                //设备故障,让上层程序 去查明具体报错信息，监听那两个变量，操作数据库完了之后再 调用resetTask方法。。
                                //logger.error(PrefixLog+"本次任务 立库出现出现异常。");
                                if(!resetTask()){
                                    logger.info(PrefixLog+",堆垛机执行任务的过程中出现Fault，并且在重置堆垛机失败 IOServer写入异常");
                                    return (T)new Integer(ResetTaskFail);
                                }
                                return (T)new Integer(DDJRunningFault);
                            }
                            Thread.sleep(1000);
                        }

                        //软终端收尾（展示用不到）
                        if(!switchs){
                            //软中断:1.重置任务；2.给前端反馈值回应；3。记录日志 ；
                            logger.info(PrefixLog+"软中断成功");
                            this.switchs = true;
                            //TODO L_STOP啥时候重置 去现场讨论
                            Integer integer = ioServerService.setTagValue(IOServerEnum.L_STOP.getCollectionPointName(), "1", 4);
                            if(integer!=0){
                                return (T)new Integer((IOServerWriteExcep));
                            }
                            if(!resetTask()){
                                return (T)new Integer(ResetTaskFail);
                            }
                            return (T)new Integer(GracefulShutdownSuccess);
                        }
                    }else {
                        logger.info(PrefixLog+"启动任务失败");
                        if(!resetTask()){
                            logger.info(PrefixLog+"启动任务失败，并且重置 堆垛机任务失败");
                            return (T)new Integer(ResetTaskFail);
                        }
                        return (T)new Integer(SendTaskFail);
                    }
                }else {
                    logger.info(PrefixLog+"，在发起堆垛机任务的时候， 往ioserver写入 起点和终点 的时候就失败了");
                    if(!resetTask()){
                        logger.info(PrefixLog+"，在发起堆垛机任务的时候， 往ioserver写入 起点和终点 的时候就失败了，并且重置任务异常");
                        return (T)new Integer(ResetTaskFail);
                    }
                    return (T)new Integer(SendTaskFail);
                }
            }else if(deviceStatus.equals(Integer.valueOf(DDJStatusEnum.Device_Status_FAULT.getDeviceStatus()))){
                //todo 故障2 发生故障后执行的后序操作（2）  这里先不要调用resetTask() 方法
                //设备故障,查明具体错误并且 写入日志，返回给前端
                logger.info(PrefixLog+"，还未发起本次任务，堆垛机已经异常");
                if(!resetTask()){
                    logger.info(PrefixLog+"，还未发起本次任务，堆垛机已经异常，并且重置任务失败");
                    return (T)new Integer(ResetTaskFail);
                }
                return (T)new Integer(DDJRunningFault);
            }
            Thread.sleep(1000);
        }
    }

    /**
     * 返回值
     *      true 代表 回库的时候 称重位置上 无障碍
     *      false 代表 回库的时候 称重位置上 有障碍
     * */

    private boolean detectOutFault(int position) {
        String fault = "";
        String senasorFault = "";
        String closeLStart = "";
        String openEndTask = "";
        switch(position)
        {
            case 1 :
                fault = IOServerEnum.Cargo_First_Fault.getCollectionPointName();
                senasorFault = IOServerEnum.Cargo_Frist_Sensor_Fault.getCollectionPointName();
                closeLStart = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                openEndTask = IOServerEnum.Cargo_Frist_End.getCollectionPointName();
                break;
            case 2 :
                fault = IOServerEnum.Cargo_Second_Fault.getCollectionPointName();
                senasorFault = IOServerEnum.Cargo_Second_Sensor_Fault.getCollectionPointName();
                closeLStart = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                openEndTask = IOServerEnum.Cargo_Second_End.getCollectionPointName();
                break;
            case 3 :
                fault = IOServerEnum.Cargo_Third_Fault.getCollectionPointName();
                senasorFault = IOServerEnum.Cargo_Third_Sensor_Fault.getCollectionPointName();
                closeLStart = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                openEndTask = IOServerEnum.Cargo_Third_End.getCollectionPointName();
                break;
            case 4 :
                fault = IOServerEnum.Cargo_Fourth_Fault.getCollectionPointName();
                senasorFault = IOServerEnum.Cargo_Fourth_Sensor_Fault.getCollectionPointName();
                closeLStart = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                openEndTask = IOServerEnum.Cargo_Fourth_End.getCollectionPointName();
                break;
            case 5 :
                fault = IOServerEnum.Cargo_Fifth_Fault.getCollectionPointName();
                senasorFault = IOServerEnum.Cargo_Fifth_Sensor_Fault.getCollectionPointName();
                closeLStart = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                openEndTask = IOServerEnum.Cargo_Fifth_End.getCollectionPointName();
                break;
            default :
                fault = null;
                senasorFault = null;
                closeLStart = null;
                openEndTask = null;
                logger.info("未知平台入口");
        }
        String FAULT = "";
        String SENASOR = "";
        int CLOSELStart=-1;
        int OPENEndTask=-1;
        try {
            FAULT=Short.toString(ioServerService.getValueByName(fault).i2Val);
            SENASOR=Short.toString(ioServerService.getValueByName(senasorFault).i2Val);
        }catch (Exception e){
            logger.info("在出库的时候，获取库位占位状态异常");
        }
        if(FAULT.equals("0") && SENASOR.equals("0")){
            return true;
        }else {
            try {
                Integer integer = ioServerService.setTagValue(closeLStart, "0", 4);
                if(integer!=0){
                    return false;
                }
            }catch (Exception e){
                logger.info("在出库的时候，获取库位占位状态异常, 并且重置的时候也出现异常");
            }
            return false;
        }
    }

    /**
     * 参数
     *      type ==1 代表入库开始重置， type ==2  代表出库开始重置
     *      position == n 代表第n个平台
     **/
    private boolean resetWeightPLC(Integer type,Integer position) {
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            return false;
        }
        String positionS = "";
        if(type == 1){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }else if(type == 2){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }
        Integer integer;
        try {
            integer = ioServerService.setTagValue(positionS, "0", 4);
        }catch (Exception e){
            System.err.println("重置plc 异常");
            return false;
        }
        if(integer!=0){
            return false;
        }
        return true;
    }

    //指定 weightPLC start
    private boolean openWeightPLCStart(Integer type, Integer position) {
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            return false;
        }
        String positionS = "";
        if(type == 1){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }else if(type == 2){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }
        Integer integer;
        try {
            integer = ioServerService.setTagValue(positionS, "1", 4);
        }catch (Exception e){
            logger.info("weightPLC 启动 异常");
            return false;
        }
        if(integer!=0){
            return false;
        }
        return true;
    }

    private boolean closeWeightPLC(Integer type,Integer position) {
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            return false;
        }
        String positionS = "";
        if(type == 1){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }else if(type == 2){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }
        Integer integer;
        try {
            integer = ioServerService.setTagValue(positionS, "0", 4);
        }catch (Exception e){
            logger.info("weightPLC 关闭 异常");
            return false;
        }
        if(integer!=0){
            return false;
        }
        return true;
    }

    //把end 置为false ,返回值：true表示 成功置为 false，false表示 把end置为 false失败。
    private boolean endWeightPLCEnd(Integer position) {

        try {
            Thread.sleep(1000);
        }catch (Exception e){
            return false;
        }
        String positionS = "";
        switch(position)
        {
            case 1 :
                positionS = IOServerEnum.Cargo_Frist_End.getCollectionPointName();
                break;
            case 2 :
                positionS = IOServerEnum.Cargo_Second_End.getCollectionPointName();
                break;
            case 3 :
                positionS = IOServerEnum.Cargo_Third_End.getCollectionPointName();
                break;
            case 4 :
                positionS = IOServerEnum.Cargo_Fourth_End.getCollectionPointName();
                break;
            case 5 :
                positionS = IOServerEnum.Cargo_Fifth_End.getCollectionPointName();
                break;
            default :
                positionS = null;
                logger.info("未知平台入口");
        }
        if(positionS==null){
            return false;
        }
        Integer integer;
        try {
            integer = ioServerService.setTagValue(positionS, "0", 4);
        }catch (Exception e){
            logger.info("weightPLC 关闭 异常");
            return false;
        }
        if(integer!=0){
            return false;
        }
        return true;
    }

    /**
     * 返回值：
     * 1.写入ioserver 异常
     * 2.重置成功
     * 3.重置失败
     **/
    public boolean resetTask(){
        // 重置任务是 不包含重置Device_Status ,这个是电控改的。
        String PrefixLog = "在执行取货位:"+takePosition+",目标位："+targetPosition+"的时候出现：";
        String endLog = "";
        if(this.weightPLCType == 1){
            endLog = "==============(入库结束)现在正在执行取货位:"+takePosition+",目标位："+targetPosition+"(入库结束)====================";
        }else {
            endLog = "==============(出库结束)现在正在执行取货位:"+takePosition+",目标位："+targetPosition+"(出库结束)====================";
        }

        //如果是出库，把称重 plc也关闭。
        if(weightPLCType == 2){
            closeWeightPLC(2,position);
        }
        
        if(weightPLCType == 1){
            boolean flag = setWHInStartToFalse(1,position);
            //false 代表 置 INSTART 为false 失败
            if(!flag){
                logger.info(PrefixLog+",在入库 任务结束后 ，关闭对应称重平台 IN_START 失败");
            }
        }

        Integer integer = -1;
        Integer integer2 = -1;
        Integer integer3 = -1;

        try {
            integer = ioServerService.setTagValue(IOServerEnum.Target_Position.getCollectionPointName(), DDJStatusEnum.ZERO.getDeviceStatus().toString(), 2);
            integer2 = ioServerService.setTagValue(IOServerEnum.Take_Position.getCollectionPointName(), DDJStatusEnum.ZERO.getDeviceStatus().toString(), 2);
            integer3 = ioServerService.setTagValue(IOServerEnum.L_Start.getCollectionPointName(), DDJStatusEnum.FALSE.getDeviceStatus().toString(), 4);
        }catch (Exception e){
            logger.info(PrefixLog+"重置任务 写入IOServer发生异常");
            logger.info(endLog);
            return false;
        }
        if(integer ==0 &&integer2 ==0 &&integer3 ==0){
            logger.info(PrefixLog+"任务重置成功");
            logger.info(endLog);
            return true;
        }else {
            logger.info(PrefixLog+"任务重置失败");
            logger.info(endLog);
            return false;
        }
    }

    private boolean setWHInStartToFalse(int type, Integer position) {
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            return false;
        }
        String positionS = "";
        if(type == 1){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }else if(type == 2){
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                    break;
                default :
                    positionS = null;
                    logger.info("未知平台入口");
            }
            if(positionS==null){
                return false;
            }
        }
        Integer integer;
        try {
            integer = ioServerService.setTagValue(positionS, "0", 4);
        }catch (Exception e){
            logger.info("在入库 任务结束后 ，关闭对应称重平台 IN_START 异常");
            return false;
        }
        if(integer!=0){
            return false;
        }
        return true;
    }

    public void shutdownGreaceful(){
        this.switchs = false;
    }
    public void wakeUpGreaceful(){
        this.switchs = true;
    }
}
